package com.zjl.itextpdf.utils;

import cn.hutool.core.util.StrUtil;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.io.font.FontProgram;
import com.itextpdf.io.font.FontProgramFactory;
import com.itextpdf.layout.font.FontProvider;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * pdf工具类
 *
 * @author zjl
 */
@Component
@AllArgsConstructor
public class PdfUtll {

    private final TemplateEngine templateEngine;

    /**
     * 将动态页面转换为静态页面，再转为pdf，最后以输出流的形式相应回去
     *
     * @param response     响应体
     * @param data         渲染数据
     * @param htmlTemplate 页面
     * @param fileName     导出的文件名
     * @param ttf          设置字体文件所在位置 null默认font/simhei.ttf
     */
    public void convertToPdf(HttpServletResponse response, Map<String, Object> data, String htmlTemplate, String fileName, String ttf) {
        // 浏览器会弹出pdf的下载功能
        response.setHeader("Content-Disposition", "filename=" + new String(String.format("%s.pdf", fileName + " - " + System.currentTimeMillis()).getBytes(), StandardCharsets.ISO_8859_1));
        convertToPdf(response, data, htmlTemplate, ttf);
    }

    /**
     * 将动态页面转换为静态页面，再转为pdf，最后以输出流的形式相应回去
     *
     * @param response     响应体
     * @param data         渲染数据
     * @param htmlTemplate 页面
     * @param ttf          设置字体文件所在位置 null默认font/simhei.ttf
     */
    public void convertToPdf(HttpServletResponse response, Map<String, Object> data, String htmlTemplate, String ttf) {
        try (OutputStream out = response.getOutputStream()) {
            // 设置 相应类型
            response.setContentType("application/pdf");

            // 将渲染数据封装到context
            Context context = new Context();
            /*
            作用使用html取值时需要点出来，例子：data.quantity
             */
            context.setVariable("data", data);
            /*
            作用使用html取值直接用key取值，例子：quantity
             */
//            context.setVariables(data);
            // 通过模板引擎将数据渲染到thymeleaf页面中 -- 自动加载resource/templates 下的html文件
            String htmlStr = templateEngine.process(htmlTemplate, context);

            // 设置转换属性
            ConverterProperties properties = setConverterProperties(ttf);

            // 转换为pdf
            HtmlConverter.convertToPdf(htmlStr, out, properties);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("响应流异常！");
        }
    }

    /**
     * 设置转换属性：字体
     *
     * @param ttf 设置字体文件所在位置 null默认font/simhei.ttf
     * @return properties
     */
    public static ConverterProperties setConverterProperties(String ttf) {
        ttf = StrUtil.nullToDefault(ttf, "font/simhei.ttf");

        try {
            ConverterProperties properties = new ConverterProperties();

            // 设置字体
            FontProvider fontProvider = new DefaultFontProvider();
            FontProgram fontProgram = FontProgramFactory.createFont(ttf);
            fontProvider.addFont(fontProgram);

            properties.setFontProvider(fontProvider);
            return properties;
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("转换字体文件不存在！");
        }
    }

}
